#!/usr/bin/env python   

"""Hello, wxPython! program."""   

import wx
import wx.lib.mixins.listctrl  as  listmix
#import images
from wx.lib.embeddedimage import PyEmbeddedImage
from utils.stream.folderstream import Folder
from utils.stream.folderstream import StatInfo
import os, os.path, sys

SmallUpArrow = PyEmbeddedImage(
    "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADxJ"
    "REFUOI1jZGRiZqAEMFGke2gY8P/f3/9kGwDTjM8QnAaga8JlCG3CAJdt2MQxDCAUaOjyjKMp"
    "cRAYAABS2CPsss3BWQAAAABJRU5ErkJggg==")
SmallDnArrow = PyEmbeddedImage(
    "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAEhJ"
    "REFUOI1jZGRiZqAEMFGke9QABgYGBgYWdIH///7+J6SJkYmZEacLkCUJacZqAD5DsInTLhDR"
    "bcPlKrwugGnCFy6Mo3mBAQChDgRlP4RC7wAAAABJRU5ErkJggg==")
Carrot = PyEmbeddedImage(
    "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAfRJ"
    "REFUWIXFV9uRgzAMXNnXEaklJdACNdACJVALlJT4PkBm/Qyvy+0ME5MYdiWtBBExFnfBvV9O"
    "12Ks8DlDjBW/vkuAe7+ca4lkADBmNs4A+k3Ez1+QJ4QxOsD1LyfGymUBSi4DwCJcC8hzIUOf"
    "ClBcEqDkuSC9iB5pKZ7b8pIHOPUzgEeUBU8yRF+MiwgxVk4LqNY9wgygwZapxypIjBVziv0D"
    "OGIlB30yTglg4+Uw0W9KOiPvlcMCSqlnMQ0WLyih+gP6Saa8VAKOlNfzKkjr3qy/PwYsLUip"
    "OCQgjl5vrGSltc9ARxeu2N0FpYHD0MC47pp6dAhboT/ZBVPFfEquhgvIeQNhlwCOXg3GYMcH"
    "vd6F+3gCKg6N4lLqs1nhZwAri/AxA7m2i8nUdJ54JefnfglVAaWBoxFz2z14z05yYGcJpsj9"
    "HLHQXC+9AdVQzEDNeEJTTYyVINomvAdGpPWnPdUSzEiNN2ObanvTDCB8KXlu12YFaPTcsuyD"
    "w+QVJB7ITTyNmut9BzlQyACnvlrv0sVHIMb6A4Bz7XIAcFO7HAAc76sdvBeAw7hdH5+LsVsJ"
    "4vc7//jEvSmPkZTgcMovQsTY5PX6isvde/nDEcyAPhxUfO+gC76R8hy86fYaba8ZYwPGJhVj"
    "YbTnvx21wvwnOQD8AjaMF/ZJlUR1AAAAAElFTkSuQmCC")
NoIcon = PyEmbeddedImage(
    "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAIxJ"
    "REFUWIXtlUsKwCAMRJPY+9+4tSshldRqP4zQyUYyanxgPqqWBGkGfZ0ABBCRZeRw3tbsfbWk"
    "0Z7XXwWIHlVLWtZa74kH/wICDOdAZCUPvN99l7OAAFMD1K33C4NXQbMP+J4e1fmV5vVbABHI"
    "meb9kcE0dxL+AqArB6Jh82QAHWKjyxD+BQQgABxgB0zmRH3prALAAAAAAElFTkSuQmCC")


class FileListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
    def __init__(self, parent, ID, pos=wx.DefaultPosition,
                 size=wx.DefaultSize, style=0):
        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
        listmix.ListCtrlAutoWidthMixin.__init__(self)
        
        
        
class FileListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin):
    def __init__(self, parent, path = "."):
        #wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
        wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
        
        tID = wx.NewId()
        
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.il = wx.ImageList(16, 16)

        self.idx1 = self.il.Add(Carrot.GetBitmap())
        self.idx2 = self.il.Add(NoIcon.GetBitmap())
        self.sm_up = self.il.Add(SmallUpArrow.GetBitmap())
        self.sm_dn = self.il.Add(SmallDnArrow.GetBitmap())

        self.list = FileListCtrl(self, tID,
                                 style=wx.LC_REPORT 
                                 #| wx.BORDER_SUNKEN
                                 #| wx.BORDER_NONE
                                 | wx.BORDER_SIMPLE
                                 | wx.LC_EDIT_LABELS
                                 | wx.LC_SORT_ASCENDING
                                 #| wx.LC_NO_HEADER
                                 #| wx.LC_VRULES
                                 #| wx.LC_HRULES
                                 #| wx.LC_SINGLE_SEL
                                 )
        
        self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
        sizer.Add(self.list, 1, wx.EXPAND)

        self.folderItem = FolderItem(getAbsPath(path))
        
        self.PopulateList()

        # Now that the list exists we can init the other base class,
        # see wx/lib/mixins/listctrl.py
        #self.itemDataMap = self.folderItem.genItemDataMap()
        listmix.ColumnSorterMixin.__init__(self, 3)
        #self.SortListItems(0, True)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)




    """
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
        self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.list)
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list)
        self.Bind(wx.EVT_LIST_DELETE_ITEM, self.OnItemDelete, self.list)
        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
        self.Bind(wx.EVT_LIST_COL_RIGHT_CLICK, self.OnColRightClick, self.list)
        self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.OnColBeginDrag, self.list)
        self.Bind(wx.EVT_LIST_COL_DRAGGING, self.OnColDragging, self.list)
        self.Bind(wx.EVT_LIST_COL_END_DRAG, self.OnColEndDrag, self.list)
        self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list)

        self.list.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
        self.list.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)


        # for wxMSW
        self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)

        # for wxGTK
        self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
    """

    def PopulateList(self):
        pass
        """
        info = wx.ListItem()
        info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
        info.m_image = -1
        info.m_format = 0
        info.m_text = "Artist"
        self.list.InsertColumnInfo(0, info)

        info.m_format = wx.LIST_FORMAT_RIGHT
        info.m_text = "Title"
        self.list.InsertColumnInfo(1, info)

        info.m_format = 0
        info.m_text = "Genre"
        self.list.InsertColumnInfo(2, info)
        """
        
        
        # columns
        info = wx.ListItem()
        info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
        info.m_image = -1
        info.m_format = wx.LIST_FORMAT_LEFT
        col = 0
        for name, visual in self.folderItem.getColumns():
            info.m_text = name
            self.list.InsertColumnInfo(col, info)
            col += 1
          
        self.list.SetColumnWidth(0, 20)
        
        
            
        #items
        """
        key = 0
        for isdir, fname, fsize in fditem.genItemData():
            print isdir, fname, fsize
            if isdir:
                index = self.list.InsertImageStringItem(sys.maxint, " ", self.idx1)
            else:
               index = self.list.InsertImageStringItem(sys.maxint, " ", self.idx2)
            self.list.SetStringItem(index, 1, fname)
            self.list.SetStringItem(index, 2, str(fsize))
            self.list.SetItemData(index, key)
            key += 1
        """    
        
        #if os.path.exists(self.curpath + os.sep + ".."):
        #(1, (False, u'filemgr.log.svn-base', 4254))
            
        self.itemDataMap = self.folderItem.genItemDataMap()
        if os.path.exists(self.folderItem.path + os.sep + ".."):
            if not (len(self.folderItem.path) == 2 and self.folderItem.path[0] != '/' and self.folderItem.path[1] == "\\"):
                self.itemDataMap[0] = (True, u"..", 0)

        items = self.itemDataMap.items()
        """
        if os.path.exists(self.folderItem.path + os.sep + ".."):
            if not (len(self.folderItem.path) == 2 and self.folderItem.path[0] != '/' and self.folderItem.path[1] == "\\"):
                items.append((0, (True, u"..", 0)))
        """
        print items
        #print items
        for key, data in items:
            if data[0]:
                index = self.list.InsertImageStringItem(sys.maxint, " ", self.idx1)
            else:
                index = self.list.InsertImageStringItem(sys.maxint, " ", self.idx2)
            self.list.SetStringItem(index, 1, data[1])
            self.list.SetStringItem(index, 2, str(data[2]))
            self.list.SetItemData(index, key)
    
    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
    def GetListCtrl(self):
        return self.list

    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
    def GetSortImages(self):
        return (self.sm_dn, self.sm_up)
        
        
class FolderItem():
    def __init__(self, path):
        #if not os.path.exists(path):
        if not os.path.isdir(path):
            path = "."
        """    
        self.path = os.path.abspath(path)
        if self.path[-1] == os.sep:
            self.path = self.path[:-1]
        """
        self.path = getAbsPath(path)
        self.folder = Folder(self.path)
    
    def changePath(self, path):
        print path
        assert os.path.isdir(path)
        self.path = path
    
    def getColumns(self):
        return [
        ("Type", False), 
        ("Name", True), 
        ("Size", True), 
        ]
    
    def genItemData(self, path = None):
        if not path:
            path = self.path
        if not os.path.isdir(path):
            return
        """       
        fullpath = os.path.abspath(path)
        if fullpath[-1] == os.sep:
            fullpath = fullpath[:-1]
        """
        self.path = getAbsPath(path)
        #fd.write("CHD %s%s" % (self.origpath, os.sep))
        self.folder.write("CHD %s" % self.path)
        ctx = self.folder.read()
        if ctx:
            filelist = ctx.split("\n")
            info = StatInfo()
            for fileinfo in filelist:
                #print fileinfo
                info.decode(fileinfo)
                yield info["isdir"], info["name"], info["size"]
            
    def genItemDataMap(self, path = None):
        map = {}
        key = 1
        for columns in self.genItemData():
            map[key] = columns
            key +=1
        return map
            

class FileBrowser(wx.SplitterWindow):
    def __init__(self, parent, id = -1, path = "."):
        #wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
        wx.SplitterWindow.__init__(self, parent, id,
                        style = wx.SP_LIVE_UPDATE
                        )
        
        #self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnSashChanged)
        self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnSashChanging)
        
        self.curpath = getAbsPath(path)
        self.textctrl = wx.TextCtrl(self, -1, self.curpath, size = (200, 40))
        self.filelist = FileListCtrlPanel(self, self.curpath)
        self.SplitHorizontally(self.textctrl, self.filelist, 40)
        
        self.currentItem = None
        
        self.filelist.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.filelist.list)
        self.filelist.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_DELETE_ITEM, self.OnItemDelete, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_COL_RIGHT_CLICK, self.OnColRightClick, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.OnColBeginDrag, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_COL_DRAGGING, self.OnColDragging, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_COL_END_DRAG, self.OnColEndDrag, self.filelist.list)
        #self.filelist.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.filelist.list)
        
        self.filelist.list.Bind(wx.EVT_LEFT_DCLICK, self.OnItemDoubleClick)
        #self.SetBackgroundColour("pink")
        
    def getColumnText(self, index, col):
        item = self.filelist.list.GetItem(index, col)
        return item.GetText()
    
    def OnItemSelected(self, evt):
        self.currentItem = evt.m_itemIndex
        print("OnItemSelected: %s, %s, %s, %s\n" %
                   (self.currentItem,
                    self.filelist.list.GetItemText(self.currentItem),
                    self.getColumnText(self.currentItem, 1),
                    self.getColumnText(self.currentItem, 2)))
        evt.Skip()
    
    def OnItemDeselected(self, evt):
        #item = evt.GetItem()
        pass
    
    def OnSashChanging(self, evt):
        #self.log.WriteText("sash changing to %s\n" % str(evt.GetSashPosition()))
        pass
        # uncomment this to not allow the change
        evt.SetSashPosition(-1)
        
    
    def OnItemDoubleClick(self, event):
        #self.log.WriteText("OnDoubleClick item %s\n" % self.list.GetItemText(self.currentItem))
        #print "OnDoubleClick item %s\n" % self.filelist.list.GetItemText(event.m_itemIndex)
        #print "OnDoubleClick item event on:", self.currentItem
        basepath = self.getColumnText(self.currentItem, 1)#self.filelist.list.GetItemText(self.currentItem)
        fullpath = os.path.abspath(self.curpath + os.sep + basepath)
        
        #print fullpath
        if os.path.isdir(fullpath):
            self.filelist.list.ClearAll()
            self.curpath = fullpath
            self.filelist.folderItem.changePath(fullpath)
            self.filelist.PopulateList()
            self.textctrl.SetValue(self.curpath)
        
        event.Skip()
        
class MgrFrame(wx.Frame):
    
    def __init__(self, image, parent=None, id=-1,   
        pos=wx.DefaultPosition, 
        title='File Manager'): 
        size = 1024, 800
        wx.Frame.__init__(self, parent, id, title, pos, size)   
        
        # add menu
        menuBar = wx.MenuBar()
        menuFile = wx.Menu()
        menuBar.Append(menuFile, "&File")
        self.SetMenuBar(menuBar)
        
        #status bar
        statusBar = self.CreateStatusBar()  
        
        #panel
        #panel = FileMgrPanel(self)
        
        #splitter
        splitter = wx.SplitterWindow(self, -1)
        #sty = wx.BORDER_NONE
        #sty = wx.BORDER_SIMPLE
        #sty = wx.BORDER_SUNKEN
        sty = wx.BORDER_THEME
    
        p1 = FileBrowser(splitter)
        p2 = FileBrowser(splitter)
        #p2.SetBackgroundColour("sky blue")
        #wx.StaticText(p2, -1, "Panel Two", (5,5))

        splitter.SetMinimumPaneSize(20)
        splitter.SplitVertically(p1, p2, self.GetClientSize().GetWidth() / 2)
        

class App(wx.App):   
    """Application class.""" 
    
    def OnInit(self): 
        self.frame = MgrFrame(None)
        self.frame.Show() 
        self.SetTopWindow(self.frame) 
        return True

def getAbsPath(path):
    if not os.path.isdir(path):
        return getAbsPath(".")
    fullpath = os.path.abspath(path)
    if fullpath[-1] == os.sep:
        if len(fullpath) == 3 and fullpath[0] != "/" and fullpath[1] == ":":
            pass
        else:
            fullpath = fullpath[:-1]
    return fullpath

def main():          
    #app = App(False)
    app = App(True, "filemgr.log")
    app.MainLoop()

if __name__ == '__main__':   
    main() 
